package c926.xiaoduyun.xiaodu.plugin.register;

import kd.bos.algo.DataSet;
import kd.bos.coderule.api.CodeRuleInfo;
import kd.bos.dataentity.OperateOption;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.metadata.ISimpleProperty;
import kd.bos.dataentity.utils.StringUtils;
import kd.bos.entity.MainEntityType;
import kd.bos.entity.cache.AppCache;
import kd.bos.entity.cache.IAppCache;
import kd.bos.entity.operate.result.OperationResult;
import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
import kd.bos.entity.plugin.args.AfterOperationArgs;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.MetadataServiceHelper;
import kd.bos.servicehelper.QueryServiceHelper;
import kd.bos.servicehelper.coderule.CodeRuleServiceHelper;
import kd.bos.servicehelper.operation.OperationServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.scm.adm.common.AdmCommonUtils;
import kd.scm.adm.service.opp.AdmRegistUserSubmitService;
import kd.scm.adm.service.valid.AdmRegistValid;
import kd.scm.common.util.SrmCommonUtil;



import java.util.*;

/**
 * 单据操作插件
 */
public class RegisterFormPluginOP extends AbstractOperationServicePlugIn {

    public AdmRegistUserSubmitService admRegistUserSubmitService = new AdmRegistUserSubmitService();
    public AdmRegistValid admRegistValid = new AdmRegistValid();
    protected IAppCache verifyCodeExpire = AppCache.get("verifyCodeExpire");


    /**
     * 提交事务执行后的处理方法
     *
     * @param e AfterOperationArgs 对象，包含操作后的数据和其他相关信息
     */
    @Override
    public void afterExecuteOperationTransaction(AfterOperationArgs e) {
        // 检查操作按钮是否为"submit"
        if (e.getOperationKey().equals("submit")) {
            DynamicObject pageDyn = e.getDataEntities()[0];
            // 从对象中获取"creditno"字段的值
            String creditno = pageDyn.getString("creditno");
            // 信用编号不为空
            if (StringUtils.isNotEmpty(creditno)) {
                // 通过信用编号从两个不同的实体中获取动态对象
                DynamicObject srmDyn = getDynByCreditno(creditno, "srm_supplierreg"); // 注册资料审批
                DynamicObject bdDyn = getDynByCreditno(creditno, "bd_supplier"); // 供应商数据库
                boolean isSucced = this.validateInfo(true, pageDyn, srmDyn, bdDyn);

                if (isSucced) {
                    addSupplier(pageDyn, srmDyn, bdDyn);
                }
                System.out.println();
            }
        }

    }

    /**
     * 添加或更新供应商信息的方法
     *
     * @param pageDyn 页面上的动态对象，包含当前操作的数据
     * @param srmDyn  SRM（供应商注册管理）动态对象，包含供应商注册的信息
     * @param bdDyn   BD（业务数据）动态对象，包含业务数据中的供应商信息
     */
    private void addSupplier(DynamicObject pageDyn, DynamicObject srmDyn, DynamicObject bdDyn) {
        // 如果 SRM 动态对象不为空
        if (srmDyn != null) {
            // 检查 SRM 动态对象的审核状态字段（auditStatus）
            if (srmDyn.get("auditStatus").equals("A") || srmDyn.get("auditStatus").equals("B")) {
                // 如果审核状态是"A"（填写资料）或"B"（提交审批），调用 fillSupplier 方法来更新资料
                fillSupplier(srmDyn, bdDyn);
            } else {
                // 如果审核状态不是"A"或"B"，代表已经审核完成，调用 change 方法来修改资料
                change(srmDyn, pageDyn);
            }
        } else if (bdDyn != null) {
            // 如果 SRM 动态对象为空，但 BD 动态对象不为空，调用 register 方法来注册新的供应商
            register(pageDyn, bdDyn);
        }
    }

    /**
     * 通过信用代码获取对应的对象
     *
     * @param creditno   信用代码
     * @param entityName 实体名称
     * @return 对应的动态对象，如果没有找到则返回null（取决于BusinessDataServiceHelper.loadSingle的实现）
     */
    private DynamicObject getDynByCreditno(String creditno, String entityName) {
        // 创建一个查询过滤器，设置过滤条件为"societycreditcode"字段等于传入的creditno
        QFilter filter = new QFilter("societycreditcode", QCP.equals, creditno);
        // 如果查询结果为空或有多条记录，具体行为取决于loadSingle方法的实现（通常返回null或抛出异常）
        return BusinessDataServiceHelper.loadSingle(entityName, new QFilter[]{filter});
    }

    private void register(DynamicObject pageDyn, DynamicObject bdDyn) {
        String enterprise = pageDyn.getString("enterprise");
        String creditno = pageDyn.getString("creditno");
        String name = pageDyn.getString("name");
        String number = pageDyn.getString("number");
        HashMap<String, String> param = new HashMap<>(4);
        param.put("number", number);
        param.put("enterprise", enterprise);
        param.put("creditno", creditno);
        param.put("name", name);
        Map<String, Object> resultMap = this.admRegistUserSubmitService.submit(param);
        if (Boolean.parseBoolean(resultMap.get("succed").toString())) {
            DynamicObject srmDyn = getDynByCreditno(creditno, "srm_supplierreg");
            fillSupplier(srmDyn, bdDyn);
        }
    }

    private void fillSupplier(DynamicObject srmDyn, DynamicObject bdDyn) {
        DynamicObject createOrg = BusinessDataServiceHelper.loadSingle("bos_org", new QFilter[]{new QFilter("id", QCP.equals, 1300553467688914944L)});
        srmDyn.set("createorg", createOrg); //创建组织
        srmDyn.set("org", createOrg); //设置审批组织
        srmDyn.set("group", getGroup());
        srmDyn.set("type", "1");
        srmDyn.set("artificialperson", "未知");
        srmDyn.set("idcard", "1");
        srmDyn.set("origin", "1");
        srmDyn.set("regcapital", 1);
        srmDyn.set("regaddress", "未知");
        srmDyn.set("telephone", srmDyn.get("phone"));
        srmDyn.set("industry", 1309590850606479360L); // 所属行业
        DynamicObjectCollection classification = srmDyn.getDynamicObjectCollection("gawv_classification");
        if (classification.size() == 0) {
            DynamicObject extdata = BusinessDataServiceHelper.loadSingle(1321860936339817472L, "srm_extdata");
            DynamicObject base = new DynamicObject(classification.getDynamicObjectType());
            base.set("fbasedataid", extdata);
            classification.add(base);
        }

        srmDyn.set("biztype", 1); //业务类型
        srmDyn.set("ctrlstrategy", 5); //控制策略 5：全局共享
        srmDyn.set("status", "B"); //数据状态
        srmDyn.set("auditStatus", "B");
        Object[] result = SaveServiceHelper.save(new DynamicObject[]{srmDyn});
        if (result.length > 0) {
            audit(srmDyn);
        }
    }

    /**
     * 对 SRM 动态对象进行审核操作
     */
    public void audit(DynamicObject srmDyn) {
        // 设置审核意见为 "同意"
        srmDyn.set("auditopinion", "同意");
        // 创建一个列表并将 SRM 动态对象添加到列表中
        List<DynamicObject> saveDatas = new ArrayList<>();
        saveDatas.add(srmDyn);
        // 创建操作选项对象
        OperateOption oprOpt = OperateOption.create();
        // 设置操作选项的特殊数据权限应用 ID 为 "srm"
        oprOpt.setVariableValue("SpecialDataPerm_CurrentAppId", "srm");
        // 设置同步标志为 true
        oprOpt.setVariableValue("bos_support_bigdata_aysn", String.valueOf(true));
        // 执行 "audit" 操作，传入操作名称、实体名称、数据和操作选项
        OperationResult r = OperationServiceHelper.executeOperate(
                "audit", "srm_supplierreg",
                saveDatas.toArray(new DynamicObject[]{}), oprOpt);
    }

    private void change(DynamicObject srmDyn, DynamicObject pageDyn) {
        boolean phoneValid = pageDyn.getString("number").equals(srmDyn.getString("phone"));
        boolean nameValid = pageDyn.getString("enterprise").equals(srmDyn.getString("name"));
        boolean linkmanVaild = pageDyn.getString("name").equals(srmDyn.getString("linkman"));
        if (!(linkmanVaild && phoneValid && nameValid)) { // 供应商状态已有审核通过，且注册资料不一致
            int seq = 1;
            int paramchguser = 3; // 参数变更用户
            if (!nameValid) paramchguser = 1;
            if (!phoneValid) paramchguser = 2;
            DynamicObject createOrg = BusinessDataServiceHelper.loadSingle("bos_org", new QFilter[]{new QFilter("id", QCP.equals, 1300553467688914944L)});
            DynamicObject change = BusinessDataServiceHelper.newDynamicObject("srm_supchange"); // 资料变更管理
            CodeRuleInfo codeRule = CodeRuleServiceHelper.getCodeRule(change.getDataEntityType().getName(), change, (String) null);
            if (codeRule != null) {
                change.set("billno", CodeRuleServiceHelper.getNumber(codeRule, change));
            }
            change.set("bizpartner", srmDyn.get("bizpartner"));
            change.set("org", createOrg);
            change.set("supplier", srmDyn);
            change.set("origin", srmDyn.get("origin"));
            change.set("paramchguser", "");
            change.set("billdate", new Date());
            change.set("billstatus", "A");

            DynamicObjectCollection entryLinks = srmDyn.getDynamicObjectCollection("entry_link");
            DynamicObjectCollection entryentity = change.getDynamicObjectCollection("entryentity");
            if (!phoneValid) {
                DynamicObject dyn = entryentity.addNew();
                dyn.set("chgfield", "账号(手机号/邮箱)");
                dyn.set("chgtype", 3);
                dyn.set("entryfieldname", "phone");
                dyn.set("fieldname", "phone");
                dyn.set("infotype", "S");
                dyn.set("newvalue", pageDyn.getString("number"));
                dyn.set("oldvalue", srmDyn.getString("phone"));
                dyn.set("srcbillid", "0");

                dyn.set("seq", seq++);

                DynamicObject oldEntryLink = entryLinks.get(0);
                DynamicObject entryLink = entryentity.addNew();
                entryLink.set("chgfield", String.format("联系人信息-原第1行 %s-手机号", oldEntryLink.getString("name1")));
                entryLink.set("chgtype", 3);
                entryLink.set("entryfieldname", "entry_link.mobile1.entryId" + oldEntryLink.getPkValue());
                entryLink.set("entryname", "entry_link");
                entryLink.set("fieldname", "mobile1");
                entryLink.set("infotype", "S");
                entryLink.set("newvalue", pageDyn.getString("number"));
                entryLink.set("oldvalue", oldEntryLink.getString("mobile1"));
                entryLink.set("srcbillentryid", oldEntryLink.getPkValue());
                entryLink.set("srcentryid", "1");
                entryLink.set("srcbillid", "0");
                entryLink.set("seq", seq++);

                change.set("paramchguser", paramchguser);
            }
            if (!linkmanVaild) {
                DynamicObject dyn = entryentity.addNew();
                dyn.set("chgfield", "系统管理员");
                dyn.set("chgtype", 3);
                dyn.set("entryfieldname", "linkman");
                dyn.set("fieldname", "linkman");
                dyn.set("infotype", "L");
                dyn.set("newvalue", String.format("zh_TW:%s;zh_CN:%s;", pageDyn.getString("name"), pageDyn.getString("name")));
                dyn.set("oldvalue", String.format("zh_TW:%s;zh_CN:%s;", srmDyn.getString("linkman"), srmDyn.getString("linkman")));
                dyn.set("other", String.format("zh_TW:::%s;;;GLang:::%s;;;zh_CN:::%s;;;", pageDyn.getString("name"), pageDyn.getString("name"), pageDyn.getString("name")));
                dyn.set("srcbillid", "0");

                dyn.set("seq", seq++);

                DynamicObject oldEntryLink = entryLinks.get(0);
                DynamicObject entryLink = entryentity.addNew();
                entryLink.set("chgfield", String.format("联系人信息-原第1行 %s-姓名", oldEntryLink.getString("name1")));
                entryLink.set("chgtype", 3);
                entryLink.set("entryfieldname", "entry_link.name1.entryId" + oldEntryLink.getPkValue());
                entryLink.set("entryname", "entry_link");
                entryLink.set("fieldname", "name1");
                entryLink.set("infotype", "S");
                entryLink.set("newvalue", pageDyn.getString("name"));
                entryLink.set("oldvalue", oldEntryLink.getString("name1"));
                entryLink.set("srcbillentryid", oldEntryLink.getPkValue());
                entryLink.set("srcentryid", "1");
                entryLink.set("srcbillid", "0");
                entryLink.set("seq", seq++);

                change.set("paramchguser", paramchguser);
            }

            if (!nameValid) {
                DynamicObject dyn = entryentity.addNew();
                dyn.set("chgfield", "名称");
                dyn.set("chgtype", 3);
                dyn.set("entryfieldname", "name");
                dyn.set("fieldname", "name");
                dyn.set("infotype", "L");
                dyn.set("newvalue", String.format("zh_TW:%s;zh_CN:%s;", pageDyn.getString("enterprise"), pageDyn.getString("enterprise")));
                dyn.set("oldvalue", String.format("zh_TW:%s;zh_CN:%s;", srmDyn.getString("name"), srmDyn.getString("name")));
                dyn.set("other", String.format("zh_TW:::%s;;;GLang:::%s;;;zh_CN:::%s;;;", pageDyn.getString("enterprise"), pageDyn.getString("enterprise"), pageDyn.getString("enterprise")));
                dyn.set("srcbillid", "0");
                dyn.set("seq", seq++);
            }

            OperationResult result = OperationServiceHelper.executeOperate("submit", "srm_supchange", new DynamicObject[]{change});
            if (result.isSuccess()) {
                OperationServiceHelper.executeOperate("cfgcfmagree", "srm_supchange", new DynamicObject[]{change});
            }


        }
    }

    /**
     * 删除空格
     */
    private void delSpace(DynamicObject pageDyn) {
        Object enterpriseobj = pageDyn.get("enterprise");
        if (enterpriseobj != null && StringUtils.isNotBlank(enterpriseobj.toString())) {
            pageDyn.set("enterprise", enterpriseobj.toString().replace(" ", ""));
        }

        Object creditnoobj = pageDyn.get("creditno");
        if (creditnoobj != null && StringUtils.isNotBlank(creditnoobj.toString())) {
            pageDyn.set("creditno", creditnoobj.toString().replace(" ", ""));
        }

        Object nameobj = pageDyn.get("name");
        if (nameobj != null && StringUtils.isNotBlank(nameobj.toString())) {
            pageDyn.set("name", nameobj.toString().replace(" ", ""));
        }

        Object numberobj = pageDyn.get("number");
        if (numberobj != null && StringUtils.isNotBlank(numberobj.toString())) {
            pageDyn.set("number", numberobj.toString().replace(" ", ""));
        }

    }

    private boolean validateInfo(boolean codeValidate, DynamicObject pageDyn, DynamicObject srmDyn, DynamicObject bdDyn) {
        this.delSpace(pageDyn);
        String enterprise = pageDyn.getString("enterprise");
        String creditno = pageDyn.getString("creditno");
        String name = pageDyn.getString("name");
        String number = null;
        if (!pageDyn.getString("number").trim().isEmpty()) {
            number = pageDyn.getString("number");
            if (number.contains("+86") && number.length() > 14) {
                number = number.substring(3, 14);
            }
        }

        if (!StringUtils.isBlank(number) && !StringUtils.isEmail(number) && !StringUtils.isPhoneNumberValid(number)) {
            this.solPhoneValid(pageDyn);
        }

        boolean isagreed = pageDyn.getBoolean("isagreed");
        boolean isSucced = true;
        if (name == null || name.trim().equals("")) {
            return false;
        } else if (StringUtils.equals("administrator", name)) {
            return false;
        }

        boolean validEnterprise = true;
        boolean validCreditno = true;
        boolean validAccount = true;
        boolean validSkyeye = true;
        boolean isBlackEnterpirse = false;
        boolean isBlackCreditno = false;
        if (StringUtils.isNotBlank(enterprise) && SrmCommonUtil.isBlackEnterpirse(0L, (String) null, enterprise)) {
            isBlackEnterpirse = true;
        }

        if (StringUtils.isNotBlank(creditno) && SrmCommonUtil.isBlackEnterpirse(0L, creditno, (String) null)) {
            isBlackCreditno = true;
        }

        if (isBlackEnterpirse && isBlackCreditno) {
            return false;
        } else if (isBlackEnterpirse) {
            return false;
        } else if (isBlackCreditno) {
            return false;
        } else  {
            validEnterprise = this.validEnterprise(enterprise, isSucced);
            validCreditno = this.validCreditno(creditno, isSucced);
        }
        // 校验账号格式
        validAccount = this.validNumber(number, isSucced, srmDyn, bdDyn);
        // 天眼查校验信用代码
        validSkyeye = this.admRegistValid.validSkyEye(enterprise, creditno, new StringBuilder(), isSucced);
        if (validEnterprise && validCreditno && validAccount && validSkyeye) {
            if (codeValidate && Objects.nonNull(number)) {
//                String validate = pageDyn.getString("validate");
//                String info = AdmCommonUtils.validateVerycode((String) this.verifyCodeExpire.get(number, String.class), validate);
//                if (StringUtils.isNotBlank(info)) {
//                    return false;
//                }

                if (!isagreed) {
                    return false;
                }
            }

            return isSucced;
        } else {
            return false;
        }
    }


    public Boolean validEnterprise(String enterprise, Boolean isSucced) {
        if (enterprise == null && enterprise.trim().equals("")) {
            isSucced = false;
        }
        return isSucced;
    }

    public Boolean validCreditno(String creditno, Boolean isSucced) {
        if (creditno == null || creditno.trim().equals("")) {
            isSucced = false;
        }
        return isSucced;
    }

    public Boolean validNumber(String number, Boolean isSucced, DynamicObject srmDyn, DynamicObject bdDyn) {
        if (number != null && !number.trim().equals("")) {
            List<String> srcRegexpert = new ArrayList<>();
            QFilter srcRegexpertQf = (new QFilter("telephone", "=", number)).or("email", "=", number);
            this.getRegisterNumberRepeatData(srcRegexpert, srcRegexpertQf, "src_regexpert", "id,number", "number");
            if (!srcRegexpert.isEmpty()) {
                return false;
            }


            List<String> bosUser = new ArrayList<>();
            QFilter bosUserQf = (new QFilter("phone", "=", number)).or("email", "=", number).and(new QFilter("enable", "=", "1"));
            this.getRegisterNumberRepeatData(bosUser, bosUserQf, "bos_user", "id,phone", "phone");
            List<String> srmUser = new ArrayList<>();
            QFilter srmUserQf = (new QFilter("enable", "=", "1")).and("number", "=", number);
            this.getRegisterNumberRepeatData(srmUser, srmUserQf, "srm_user", "id,number", "number");
            List<String> srmSupplierReg = new ArrayList<>();
            QFilter srmSupplierRegQf = new QFilter("phone", "=", number);
            this.getRegisterNumberRepeatData(srmSupplierReg, srmSupplierRegQf, "srm_supplierreg", "id,number", "number");
            List<String> purSupUser = new ArrayList<>();
            QFilter purSupUserQf = (new QFilter("user.phone", "=", number)).or("user.email", "=", number).and(new QFilter("enable", "=", "1"));
            this.getRegisterNumberRepeatData(purSupUser, purSupUserQf, "pur_supuser", "id,number", "number");


            if (!bosUser.isEmpty() || !purSupUser.isEmpty() || !srmSupplierReg.isEmpty() || !srmUser.isEmpty()) {
                if (srmDyn == null && bdDyn == null) { // 两个都为空，手机不属于此供应商，但是手机已注册，所以不能注册
                    return false;
                } else { // 供应商不为空，但是手机号都不属于供应商，手机已注册
                    if ((srmDyn != null && srmDyn.getString("phone").equals("number")) && (bdDyn != null && bdDyn.getString("phone").equals("number"))) {
                        return isSucced;
                    } else if (!(srmDyn != null && srmDyn.getString("phone").equals("number"))) {
                        return isSucced;
                    } else if ((bdDyn != null && bdDyn.getString("phone").equals("number"))) {
                        return isSucced;
                    } else {
                        return false;
                    }
                }
            }
        } else {
            return false;
        }
        return isSucced;
    }
    // 校验手机格式
    private void solPhoneValid(DynamicObject pageDyn) {
        String number = pageDyn.getString("number");
        if (StringUtils.isNotBlank(number)) {
            int charnum = 0;

            int i;
            for (i = 0; i < number.length(); ++i) {
                if (number.charAt(i) == '-') {
                    ++charnum;
                }
            }

            if (charnum != 0) {
                String[] split = number.split("-", 2);
                if (split[0].equals("86")) {
                    number = number.substring(3);
                    --charnum;
                }
            }

            for (i = 0; i < charnum - 1; ++i) {
                int index = number.indexOf(45);
                number = number.substring(0, index) + number.substring(index + 1);
            }

            pageDyn.set("number", number);
        }

    }
    private Object getGroup() {
        return BusinessDataServiceHelper.loadSingle("bd_suppliergroup", "id,level", new QFilter[]{new QFilter("number", QCP.equals, "GYS03")});
    }

    private void getRegisterNumberRepeatData(List<String> phoneRepeatList, QFilter qf, String eneityName, String selects, String entityPhone) {
        DataSet dataSet = QueryServiceHelper.queryDataSet("AdmRegisterPlugin", eneityName, selects, new QFilter[]{qf}, "id");
        Throwable var7 = null;

        try {
            dataSet.forEach((row) -> {
                phoneRepeatList.add(row.getString(entityPhone));
            });
        } catch (Throwable var16) {
            var7 = var16;
            throw var16;
        } finally {
            if (dataSet != null) {
                if (var7 != null) {
                    try {
                        dataSet.close();
                    } catch (Throwable var15) {
                        var7.addSuppressed(var15);
                    }
                } else {
                    dataSet.close();
                }
            }

        }

    }

}